package restless.core.managers {
	
	import flash.net.getClassByAlias;
	import flash.net.SharedObject;
	import flash.net.registerClassAlias;
	import flash.utils.getQualifiedClassName;
	import restless.core.RLEAchievement;
	import restless.core.RLEStat;
	import restless.core.gameObjs.RLEUpdateRenderObj;
	
	/**
	 * @author Jordan Laine
	 * 5/28/12
	 * 3/14/13
	 * 5/29/14
	 */
	
	public class RLEStatManager extends RLEUpdateRenderObj {
		
		protected var vStats:Vector.<RLEStat>;
		protected var statStrings:Array = [];
		protected var achievementStrings:Array = [];
		protected var vAchievements:Vector.<RLEAchievement> = new Vector.<RLEAchievement>;
		protected var nStats:int = 0;
		protected var tempStat:RLEStat;
		protected var gameID:String;
		private var _sharedObject:SharedObject;
		
		public const trackSession:int = 1;
		public const trackCurrent:int = 2;
		public const trackHistory:int = 3;
		
		private var i:int;
		
		public function RLEStatManager(gameID:String) {
			
			this.gameID = gameID;
			registerClassAlias("restless.core.RLEStat", RLEStat);
			
			_sharedObject = SharedObject.getLocal(gameID);
			
			// game has yet to run, or game has run but the array in sharedObject is empty, init
			if ( _sharedObject.data.vStats == undefined || vStats == null || _sharedObject.data.vStats.length < 0) {
				initSharedObj();
			 
			// game has been run before, stats are present
			} else {
				vStats = _sharedObject.data.vStats as Vector.<RLEStat>;
				statStrings = new Vector.<String>;
				i = vStats.length-1;
				if (i > -1) {
					for (i; i > -1; i--) {
						tempStat = vStats[i];
						statStrings.push( tempStat.id );
					}
				}
			}
			
			tempStat = null;
			updateLocalObj();
		}
		
		private function initSharedObj():void {
			_sharedObject.data.vStats = new Vector.<RLEStat>;
			vStats = _sharedObject.data.vStats;
			addStats(statStrings);
			updateLocalObj();
		}
		
		public function addToStat(id:String, num:Number):void {
			var tempnum:int = statStrings.indexOf(id);
			if (tempnum > -1) {
				tempStat = vStats[tempnum];
			} else {
				addStat(id);
			}
			
			tempStat.add(num);
		}
		
		public function addStat(id:String, resetable:Boolean = false, negative:Boolean = false):RLEStat {
			var stat:String = id;
			var tempnum:int = statStrings.indexOf(stat);
			if (tempnum < 0) {
				tempStat = new RLEStat();
				var num:uint = statStrings.push(stat);
				nStats++;
				tempStat.init( gameID, id, num, resetable, negative);
				vStats.push(tempStat);
				tempStat.traceData();
				return tempStat;
			} else {
				return null;
			}
		}
		
		// pass strings
		public function addStats(stats:Array):void {
			i = stats.length - 1
			for (i; i > -1; i--) {
				addStat(stats[i]);
			}
		}
		
		public function getStats(strings:Array = null):Vector.<RLEStat> {
			// add range paramater?
			if (strings == null) { return vStats; }
			
			var num:int;
			var stats:Vector.<RLEStat> = new Vector.<RLEStat>;
			
			i = strings.length -1;
			for (i; i > -1; i--) {
				num = statStrings.indexOf(strings[i]);
				stats.push(vStats[num]);
			}
			return stats;
		}
		
		public function getStat(id:String):RLEStat {
			var num:int = statStrings.indexOf(id);
			if (num > -1) {
				if (vStats.length-1 < num) { return null; }
				return vStats[num];
			} else {
				trace("no stat found");
				return null;
			}
		}
		
		public function getStatIDs():Array {
			return statStrings;
		}
		
		public function addAchievement(id:String, statID:String, goal:Number, trackID:int,	iconBlitString:String = "", 
			resetable:Boolean = false):RLEAchievement 
		{
			
			i = achievementStrings.indexOf(id)
			if (i > -1) { return vAchievements[i]; }
			
			var achievo:RLEAchievement = new RLEAchievement(id);
			achievo.nID = vAchievements.push(achievo);
			
			i = statStrings.indexOf(statID);
			if (i > -1) {
				//compile and run time errors
				achievo.stat = vStats[i];
			} else {
				achievo.stat = addStat(statID, resetable);
			}
			
			if (trackID == trackCurrent) {
				achievo.trackCurrent(true);
			} else if (trackID == trackHistory) {
				achievo.trackHistory(true);
			} else if (trackID == trackSession) {
				achievo.trackSession(true);
			} else {
				trace("Use the Stats Manager's tracking consts.");
			}
			
			if (iconBlitString != "") { achievo.iconBlitString = iconBlitString; }
			achievo.goal = goal;
			achievementStrings.push(id);
			return achievo;
		}
		
		public function getAchievement(id:String):RLEAchievement {
			var num:int = achievementStrings.indexOf(id);
			if (num > -1) {
				return vAchievements[num];
			} else {
				trace("no stat found");
				return null;
			}
		}
		
		public function getAchievements(strings:Array = null):Vector.<RLEAchievement> {
			if (strings == null) { return vAchievements; }
			
			var num:int;
			var achievos:Vector.<RLEAchievement> = new Vector.<RLEAchievement>;
			
			i = strings.length -1;
			for (i; i > -1; i--) {
				num = achievementStrings.indexOf(strings[i]);
				achievos.push(vStats[num]);
			}
			return achievos;
		}
		
		public function resetCurrentCount():void {
			i = vStats.length -1;
			for (i; i > -1; i--) {
				vStats[i].resetCurrent();
			}
		}
		
		public function resetSessionCount():void {
			i =vStats.length -1;
			for (i; i > -1; i--) {
				vStats[i].resetSession();
			}
		}
		
		public function getSessionValue(id:String):Number {
			var num:int = statStrings.indexOf(id);
			if (num >= 0) {
				return vStats[num].sessionCount;
			} else {
				return 0;
			}
		}
		
		public function clear():void {
			_sharedObject.clear();
		}
		
		//Call this to manually update the local objects
		public function updateLocalObj():void {
			trace("SHARED OBJECT SIZE IS " + (_sharedObject.size / 1024) +" KB");
			_sharedObject.flush();
			trace("SHARED OBJECT UPDATED, NEW SIZE IS " + (_sharedObject.size / 1024) +" KB");
		}	
	}
}